package triannon.client.map;

import java.util.Random;

import triannon.client.settings.LevelProperties;
import triannon.client.sprites.Background;
import triannon.client.sprites.Building;
import triannon.client.sprites.Environment;
import triannon.client.sprites.Field;
import triannon.client.sprites.Fraction;
import triannon.client.sprites.Unit;
import triannon.client.util.TMath;
import triannon.client.util.XMLIO;

public final class MapFactory {
	public static IMap createRandomLevel() {
		IMap level = new Map(96, 96);

		Field sprites = level.getField();

		initRandomTrees(level);
		for (int x = 0; x < level.getWidth(); x += LevelProperties.getGridSize()) {
			for (int y = 0; y < level.getHeight(); y += LevelProperties.getGridSize()) {
				sprites.add(new Background("grass1", x, y));
			}
		}

		sprites.add(new Building("hut1", Fraction.OWN, TMath.toWorldCoorninates(4),
				TMath.toWorldCoorninates(4)));

		Building h = new Building("hut1", Fraction.ENEMY, TMath
				.toWorldCoorninates(level.getMapWidth() - 4), TMath
				.toWorldCoorninates(level.getMapHeight() - 4));

		sprites.add(h);

		sprites.add(new Unit("grunt", Fraction.ENEMY, TMath
				.toWorldCoorninates(level.getMapWidth() - 5), TMath
				.toWorldCoorninates(level.getMapHeight() - 3), 0.13d));
		sprites.add(new Unit("grunt", Fraction.ENEMY, TMath
				.toWorldCoorninates(level.getMapWidth() - 8), TMath
				.toWorldCoorninates(level.getMapHeight() - 2), 0.5d));
		sprites.add(new Unit("grunt", Fraction.ENEMY, TMath
				.toWorldCoorninates(level.getMapWidth() - 7), TMath
				.toWorldCoorninates(level.getMapHeight() - 4), 0.9d));

		System.err.println("Created a level with size " + level.getWidth() + "x"
				+ level.getHeight());
		System.err.println("Sprites: " + sprites);

		XMLIO.writeXML(level, "defaultmap.xml");

		return level;
	}

	public static IMap createRandomLevelNewStyle() {
		IMap level = new Map(128, 96);

		Field sprites = level.getField();

		for (int x = 0; x < level.getWidth(); x += LevelProperties.getGridSize() * 2) {
			for (int y = 0; y < level.getHeight(); y += LevelProperties.getGridSize() * 2) {
				sprites.add(new Background("sand1", x, y));
			}
		}

		initRandomStones(level);

		sprites.add(new Building("geosphere1", Fraction.OWN, TMath
				.toWorldCoorninates(4), TMath.toWorldCoorninates(4)));

		sprites.add(new Unit("tank1", Fraction.OWN, TMath.toWorldCoorninates(7),
				TMath.toWorldCoorninates(9), 0.66d));
		sprites.add(new Unit("tank1", Fraction.OWN, TMath.toWorldCoorninates(4),
				TMath.toWorldCoorninates(7), 1.d));
		sprites.add(new Unit("tank1", Fraction.OWN, TMath.toWorldCoorninates(7),
				TMath.toWorldCoorninates(3), 1.d));
		sprites.add(new Unit("tank1", Fraction.OWN, TMath.toWorldCoorninates(12),
				TMath.toWorldCoorninates(8), 1.d));
		sprites.add(new Unit("tank1", Fraction.OWN, TMath.toWorldCoorninates(8),
				TMath.toWorldCoorninates(9), 1.d));

		sprites.add(new Building("tower1", Fraction.OWN, TMath
				.toWorldCoorninates(14), TMath.toWorldCoorninates(3)));
		sprites.add(new Building("tower1", Fraction.OWN, TMath
				.toWorldCoorninates(14), TMath.toWorldCoorninates(5)));

		sprites.add(new Building("hut1", Fraction.ENEMY, TMath
				.toWorldCoorninates(level.getMapWidth() - 4), TMath
				.toWorldCoorninates(level.getMapHeight() - 4)));

		sprites.add(new Unit("grunt", Fraction.ENEMY, TMath
				.toWorldCoorninates(level.getMapWidth() - 5), TMath
				.toWorldCoorninates(level.getMapHeight() - 3), 0.13d));
		sprites.add(new Unit("grunt", Fraction.ENEMY, TMath
				.toWorldCoorninates(level.getMapWidth() - 8), TMath
				.toWorldCoorninates(level.getMapHeight() - 2), 0.5d));
		sprites.add(new Unit("grunt", Fraction.ENEMY, TMath
				.toWorldCoorninates(level.getMapWidth() - 7), TMath
				.toWorldCoorninates(level.getMapHeight() - 4), 0.9d));

		System.err.println("Created a level with size " + level.getWidth() + "x"
				+ level.getHeight());
		System.err.println("Sprites: " + sprites);

		// XMLIO.writeXML(level, "defaultmap.xml");

		return level;
	}

	public static void initRandomTrees(IMap level) {
		Random rnd = new Random(System.currentTimeMillis());

		int size = level.getHeight();
		int halfSize = size / 2;

		for (int x = 0; x < level.getWidth(); x += LevelProperties.getGridSize()) {

			for (int y = 0; y < level.getHeight(); y += LevelProperties.getGridSize()) {
				double chanceX = Math.abs(halfSize - x) / (double) size;
				double chanceY = Math.abs(halfSize - y) / (double) size;

				chanceX = Math.pow(chanceX, 2);
				chanceY = Math.pow(chanceY, 2);

				if (rnd.nextDouble() < chanceX || rnd.nextDouble() < chanceY) {
					if (rnd.nextBoolean()) {
						level.getField().add(new Environment("tree1", x, y));
					} else {
						level.getField().add(new Environment("tree2", x, y));
					}
				}
			}
		}
	}

	public static void initRandomStones(IMap level) {
		Random rnd = new Random(System.currentTimeMillis());

		for (int x = 0; x < level.getWidth(); x += LevelProperties.getGridSize()) {
			for (int y = 0; y < level.getHeight(); y += LevelProperties.getGridSize()) {
				double chance = 0.1d;

				if (rnd.nextDouble() < chance) {
					level.getField().add(
							new Environment("stone" + (rnd.nextInt(4) + 1), x, y));
				}
			}
		}
	}
}
